Package ru.dubov.polygontriangulation

Source Code of ru.dubov.polygontriangulation.VanGoghPolygon

package ru.dubov.polygontriangulation;
import ru.dubov.primitives.Point;
import ru.dubov.primitives.Polygon;
import ru.dubov.primitives.Triangle;

/**
* An advanced version of polygon (with "ears")
* for O(n^2) Van Gogh implementation.
* The implementation involves using double linked
* cyclic lists for storing the vertices.
*/
public class VanGoghPolygon {
   
    public VanGoghPolygon() {
        vertices = new DoublyLinkedCyclicList<Point>();
        ears = new DoublyLinkedCyclicList<DoublyLinkedCyclicList<Point>.Node>();
    }
   
    public VanGoghPolygon(Polygon p) {
        this();
       
        for (int i = p.size()-1; i >= 0; i--) {
            vertices.insert(p.get(i));
        }
       
        constructEarList();
    }
   
    /*private void listVert() {
        DoublyLinkedCyclicList<Point>.Node cur = vertices.head();
        System.out.println();
        do {
            System.out.print(cur.value+" ");
            cur = cur.next;
        } while(cur != vertices.head());
        System.out.println();
    }*/
   
    public Triangle removeEar() {
       
        DoublyLinkedCyclicList<Point>.Node adjLeft = ears.head().value.prev;
        DoublyLinkedCyclicList<Point>.Node adjRight = ears.head().value.next;
       
        Triangle ear = new Triangle(adjLeft.value,
                ears.head().value.value, adjRight.value);     

        ears.head().value.delete(); // Delete in vertices
        ears.head().delete(); // Delete in ears
       
        if (isConvex(adjLeft, isClockwise)) {
            // not an ear anymore?
            if (adjLeft == ears.head().prev.value) {
                if (! isEar(ears.head().prev.value, isClockwise)) {
                    ears.head().prev.delete();
                }
            // new ear?
            } else if (isEar(adjLeft, isClockwise)) {
                ears.insert(adjLeft);
                ears.next();
            }
        }
       
        // next has now become the head (after deleting)
       
        if (isConvex(ears.head().value, isClockwise)) {
            // not an ear anymore?
            if (adjRight == ears.head().value) {
                if (! isEar(ears.head().value, isClockwise)) {
                    ears.head().delete();
                }
            // new ear?
            } else if (isEar(adjRight, isClockwise)) {
                ears.insert(adjRight);
            }
        }
       
        return ear;
    }
   
    public final void constructEarList() {
        DoublyLinkedCyclicList<Point>.Node cur = vertices.head();
        if (cur == null) return;
       
        isClockwise = isClockwise();
       
        // Building the ear list for O(n^2) time.
       
        cur = vertices.head().prev;
        do {
            if (isEar(cur, isClockwise)) {
                ears.insert(cur);
            }
            cur = cur.prev;
        } while(cur != vertices.head().prev);
    }
   
    private boolean isConvex(DoublyLinkedCyclicList<Point>.Node node, boolean isClockwise) {
        return Point.isLeftTurn(node.prev.value, node.value, node.next.value)
               ^ isClockwise;
    }
   
    /*private boolean isReflex(DoublyLinkedList<Point>.Node node, boolean isClockwise) {
        return ! isConvex(node, isClockwise);
    }*/
   
    /**
     * O(n)
     */
    private boolean isEar(DoublyLinkedCyclicList<Point>.Node node, boolean isClockwise) {
       
        if (! isConvex(node, isClockwise)) {
            return false;
        }
       
        Triangle tr = new Triangle(node.prev.value, node.value, node.next.value);
       
        DoublyLinkedCyclicList<Point>.Node cur = vertices.head();
        do {
            if (tr.pointInside(cur.value)) return false;
            cur = cur.next;
        } while(cur != vertices.head());
       
        return true;
    }
   
    public boolean isClockwise() {
        double sum = 0;
       
        DoublyLinkedCyclicList<Point>.Node cur = vertices.head();
       
        do {
            sum += (cur.next.value.getX() - cur.value.getX())*
                    (cur.next.value.getY() + cur.value.getY());
           
            cur = cur.next;
        } while(cur != vertices.head());
       
        return (sum > 0);
    }
   
    private DoublyLinkedCyclicList<Point> vertices;
    private DoublyLinkedCyclicList<DoublyLinkedCyclicList<Point>.Node> ears;
    private boolean isClockwise;
}
TOP

Related Classes of ru.dubov.polygontriangulation.VanGoghPolygon

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.